//
//  _iOSUtils_Geometry.h
//  iOSUtils
//
//  Created by HJC on 11-9-8.
//  Copyright 2011年 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>


////////////////////////
#pragma mark 数组操作函数的大小
#define ArraySizeOf(array)  (sizeof(array) / sizeof(array[0]))

// 在数组中[begin, end)查找val的位置, 返回 0 表示找不到
extern CGFloat* ArrayFindCGFloat(CGFloat* begin, CGFloat* end, CGFloat val);
extern NSInteger* ArrayFindNSInteger(NSInteger* begin, NSInteger* end, NSInteger val);


inline static void SafelyRelease(NSObject** p)
{
    [*p release];
    *p = nil;
}

////////////////////////////////////
#pragma mark 三个交换函数
inline static void SwapNSObject(NSObject** a, NSObject** b)
{
    NSObject* tmp = *a;
    *a = *b;
    *b = tmp;
}


inline static void SwapCGFloat(CGFloat* a, CGFloat* b)
{
    CGFloat tmp = *a;
    *a = *b;
    *b = tmp;
}


inline static void SwapNSInteger(NSInteger* a, NSInteger* b)
{
    CGFloat tmp = *a;
    *a = *b;
    *b = tmp;
}


//////////////////////
#pragma mark NSInteger的一些函数
// 将一个十六进进度的字符，转成数字值
inline static NSInteger NSIntegerFromHexChar(unichar c)
{
    // 数字
	if (c >= '0' && c <= '9')
	{
        return (c - '0');
	}
    
    // 小写字母
	if (c >= 'a' && c <= 'f')
	{
		return (c - 'a' + 10);
	}
    
    // 大写字母
	if (c >= 'A' && c <= 'F')
	{
		return  (c - 'A' + 10);
	}
    
    return 0;
}


inline static NSInteger Random(NSInteger begin, NSInteger end)
{
    return (rand() % (end - begin)) + begin;
}


//////////////////////////////////////
#pragma mark CGFloat的一些函数
// 比较两个浮点数是否相等
inline static BOOL CGFloatEqualToFloat(CGFloat val0, CGFloat val1)
{
	CGFloat dist = val0 - val1;
	return fabsf(dist) < FLT_EPSILON;
}


// 判断浮点数是否为0
inline static BOOL CGFloatIsZero(CGFloat val)
{
	return CGFloatEqualToFloat(val, 0.0f);
}



//////////////////////////////////
#pragma mark 弧度和角度相互转换
inline static CGFloat RadianFromDegree(CGFloat degree)
{
    return (M_PI * (degree / 180.0f));
}


inline static CGFloat DegreeFromRadian(CGFloat radian)
{
    return (180.0f * (radian / M_PI));
}



///////////////////////
#pragma mark CGPoint的一些函数

// 得到两点之间的距离
inline static CGFloat CGPointDistanceTo(CGPoint p0, CGPoint p1)
{
    CGFloat offsetX = p0.x - p1.x;
    CGFloat offsetY = p0.y - p1.y;
    return sqrtf(offsetX * offsetX + offsetY * offsetY);
}

// 偏移点
inline static CGPoint CGPointOffset(CGPoint pt, CGFloat dx, CGFloat dy)
{
    return CGPointMake(pt.x + dx, pt.y + dy);
}


// 两点相减
inline static CGSize CGPointMinusPoint(CGPoint pt0, CGPoint pt1)
{
    return CGSizeMake(pt0.x - pt1.x, pt0.y - pt1.y);
}

// 点和size相加
inline static CGPoint CGPointAddSize(CGPoint pt, CGSize size)
{
    return CGPointMake(pt.x + size.width, pt.y + size.height);
}


///////////////////////////
#pragma mark CGRect的一些函数

// 得到矩形的中心点
inline static CGPoint CGRectGetMiddle(CGRect rect)
{
    CGFloat xpos = rect.origin.x + rect.size.width * 0.5f;
    CGFloat ypos = rect.origin.y + rect.size.height * 0.5f;
    return CGPointMake(xpos, ypos);
}

// 设置矩形的中心点
inline static void CGRectSetMiddle(CGRect* rect, CGPoint middle)
{
    rect->origin.x = middle.x - rect->size.width * 0.5f;
    rect->origin.y = middle.y - rect->size.height * 0.5f;
}


// 得到数据点合起来的包围框, 但count不能为0
extern CGRect CGRectBoundsOfPoints(CGPoint* points, NSInteger count);

// 重新设置包围框
inline static void CGRectBoundsReset(CGRect* rect, CGPoint point)
{
    rect->origin = point;
    rect->size.width = 0.0f;
    rect->size.height = 0.0f;
}

// 往包围框中添加点, 注意矩形一定要是规范的，也就是width和height要大于0
inline static void CGRectBoundsAddPoint(CGRect* rect, CGPoint point)
{
    CGPoint minPt = rect->origin;
    CGPoint maxPt = CGPointAddSize(rect->origin, rect->size);
    
    minPt.x = MIN(minPt.x, point.x);
    minPt.y = MIN(minPt.y, point.y);
    
    maxPt.x = MAX(maxPt.x, point.x);
    maxPt.y = MAX(maxPt.y, point.y);
    
    rect->origin = minPt;
    rect->size = CGPointMinusPoint(maxPt, minPt);
}


